package cn.wolfcode.wolf2w.note.service.impl;

import cn.wolfcode.wolf2w.common.core.constant.SecurityConstants;
import cn.wolfcode.wolf2w.common.core.domain.R;
import cn.wolfcode.wolf2w.common.core.exception.ServiceException;
import cn.wolfcode.wolf2w.member.api.RemoteUserInfoService;
import cn.wolfcode.wolf2w.member.api.domain.UserInfo;
import cn.wolfcode.wolf2w.note.api.domain.Note;
import cn.wolfcode.wolf2w.note.api.domain.NoteContent;
import cn.wolfcode.wolf2w.note.mapper.NoteContentMapper;
import cn.wolfcode.wolf2w.note.mapper.NoteMapper;
import cn.wolfcode.wolf2w.note.query.NoteQuery;
import cn.wolfcode.wolf2w.note.query.TravelCondition;
import cn.wolfcode.wolf2w.note.service.INoteService;
import cn.wolfcode.wolf2w.note.vo.AuditVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

/**
 * 旅游日记Service业务层处理
 * 
 * @author dafei
 * @date 2023-11-25
 */
@Service
@Transactional
public class NoteServiceImpl extends ServiceImpl<NoteMapper,Note> implements INoteService {


    @Autowired
    private RemoteUserInfoService remoteUserInfoService;

    @Autowired
    private NoteContentMapper noteContentMapper;

    @Override
    public IPage<Note> queryPage(NoteQuery qo) {
        IPage<Note> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        LambdaQueryChainWrapper<Note> wrapper = lambdaQuery().eq(qo.getDestId() != null, Note::getDestId, qo.getDestId());
        //出行天数
        TravelCondition day = TravelCondition.DAY_MAP.get(qo.getDayType());
        //出行时间
        TravelCondition time = TravelCondition.TIME_MAP.get(qo.getTravelTimeType());
        //人均消费
        TravelCondition avg = TravelCondition.CONSUME_MAP.get(qo.getConsumeType());
        if(day != null){
            wrapper.between(Note::getDays, day.getMin(), day.getMax());
        }

        if(time != null){
            //wrapper.between("MONTH(travel_time)", time.getMin(), time.getMax());
            wrapper.apply("MONTH(travel_time) between {0} and {1}", time.getMin(), time.getMax());
        }

        if(avg != null){
            wrapper.between(Note::getAvgConsume, avg.getMin(), avg.getMax());
        }
        //排序
        wrapper.orderByDesc(StringUtils.hasText(qo.getOrderBy()), "viewnum".equals(qo.getOrderBy())?Note::getViewnum:Note::getCreateTime);

        wrapper.page(page);
        //额外处理auther对象
        for (Note o : page.getRecords()) {
            R<UserInfo> ret = remoteUserInfoService.getOne(o.getAuthorId(), SecurityConstants.INNER);
            if(ret != null && R.isSuccess(ret)){
                o.setAuthor(ret.getData());
            }
        }
        return page;
    }

    @Override
    public NoteContent getContent(Long id) {
        return noteContentMapper.selectById(id);
    }

    @Override
    public void audit(AuditVO vo) {

        //审核条件
        Note note = super.getById(vo.getId());
        if(note == null || note.getStatus() != Note.STATE_WAITING){
            throw new ServiceException("参数异常");
        }
        //审核通过
        if(vo.getStatus() == Note.STATE_RELEASE){
            //1：改状态：通过
            note.setStatus(Note.STATE_RELEASE);
            //2: 发布时间：now
            note.setReleaseTime(new Date());
            //3: 更新时间： now
            note.setUpdateTime(new Date());
            //4: 记录审核信息 （审核人，审核状态， 审核备注，审核时间， 审核记录....）  @TODO
            super.updateById(note);
        }else{
            //审核拒绝
            //1：改状态：拒绝
            note.setStatus(Note.STATE_REJECT);
            //2: 发布时间：null
            note.setReleaseTime(null);
            //3: 更新时间： now
            note.setUpdateTime(new Date());
            //4: 记录审核信息 （审核人，审核状态， 审核备注，审核时间， 审核记录....）  @TODO
            super.updateById(note);
            //lambdaUpdate().set().update()
        }
    }

    @Override
    public List<Note> queryViewnumTop3(Long destId) {
        return lambdaQuery().eq(Note::getDestId, destId).orderByDesc(Note::getViewnum).last("limit 3").list();
    }
}
